class Main extends egret.DisplayObjectContainer {

    /**
     * 加载进度界面
     * Process interface loading
     */
    private loadingView: LoadingUI;

    public constructor() {
        super();
        this.addEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this);
    }

    private onAddToStage(event: egret.Event) {
        //设置加载进度界面
        //Config to load process interface
        this.loadingView = new LoadingUI();
        this.stage.addChild(this.loadingView);

        //初始化Resource资源加载库
        //initiate Resource loading library
        RES.addEventListener(RES.ResourceEvent.CONFIG_COMPLETE, this.onConfigComplete, this);
        RES.loadConfig("resource/default.res.json", "resource/");
    }

    /**
     * 配置文件加载完成,开始预加载preload资源组。
     * configuration file loading is completed, start to pre-load the preload resource group
     */
    private onConfigComplete(event: RES.ResourceEvent): void {
        RES.removeEventListener(RES.ResourceEvent.CONFIG_COMPLETE, this.onConfigComplete, this);
        RES.addEventListener(RES.ResourceEvent.GROUP_COMPLETE, this.onResourceLoadComplete, this);
        RES.addEventListener(RES.ResourceEvent.GROUP_LOAD_ERROR, this.onResourceLoadError, this);
        RES.addEventListener(RES.ResourceEvent.GROUP_PROGRESS, this.onResourceProgress, this);
        RES.addEventListener(RES.ResourceEvent.ITEM_LOAD_ERROR, this.onItemLoadError, this);
        RES.loadGroup("preload");
    }

    /**
     * preload资源组加载完成
     * Preload resource group is loaded
     */
    private onResourceLoadComplete(event: RES.ResourceEvent) {
        if (event.groupName == "preload") {
            this.stage.removeChild(this.loadingView);
            RES.removeEventListener(RES.ResourceEvent.GROUP_COMPLETE, this.onResourceLoadComplete, this);
            RES.removeEventListener(RES.ResourceEvent.GROUP_LOAD_ERROR, this.onResourceLoadError, this);
            RES.removeEventListener(RES.ResourceEvent.GROUP_PROGRESS, this.onResourceProgress, this);
            RES.removeEventListener(RES.ResourceEvent.ITEM_LOAD_ERROR, this.onItemLoadError, this);
            this.createGameScene();
        }
    }

    /**
     * 资源组加载出错
     *  The resource group loading failed
     */
    private onItemLoadError(event: RES.ResourceEvent) {
        console.warn("Url:" + event.resItem.url + " has failed to load");
    }

    /**
     * 资源组加载出错
     *  The resource group loading failed
     */
    private onResourceLoadError(event: RES.ResourceEvent) {
        //TODO
        console.warn("Group:" + event.groupName + " has failed to load");
        //忽略加载失败的项目
        //Ignore the loading failed projects
        this.onResourceLoadComplete(event);
    }

    /**
     * preload资源组加载进度
     * Loading process of preload resource group
     */
    private onResourceProgress(event: RES.ResourceEvent) {
        if (event.groupName == "preload") {
            this.loadingView.setProgress(event.itemsLoaded, event.itemsTotal);
        }
    }
    private textfield: egret.TextField;

    /**
     * 创建游戏场景
     * Create a game scene
     */
    private createGameScene() {
        var This = this;
        this.width = 640;
        this.height = 1136;
        var dibanX = (this.width - 35 * 16) / 2;//地图距离左边的距离
        var dibanY = (this.height - 35 * 16) / 2;//地图距离上边的距离
        var renimg = "down_png";//人物的显示方向图片
        var renX, renY;//当前关卡的人物的x,y坐标
        var picArr = [];//地图添加物品对象数组
        var guanqiaNum = 0;//关卡关数
        var guanqiaText;//显示关卡文本对象



        //铺地板
        dibanFn();
        function dibanFn() {
            for (let i = 0; i < 16; i++) {
                for (let j = 0; j < 16; j++) {
                    var dibanBitmap = new egret.Bitmap(RES.getRes("block_gif"));
                    dibanBitmap.x = j * 35 + dibanX;
                    dibanBitmap.y = i * 35 + dibanY;
                    dibanBitmap.width = 35;
                    dibanBitmap.height = 35;
                    dibanBitmap.touchEnabled = true;
                    This.addChild(dibanBitmap);
                }
            }
        }




        //添加按钮（上一关/重玩本关/下一个）
        var btnWidth = 150, btnHeight = 50;
        var btnX = (640 - btnWidth * 3) / 4;
        var btnY = (dibanY + 35 * 16) + 40;
        var prevButton = createButton(btnX, btnY, btnWidth, btnHeight, 0x000000, "上一关", 0xffffff);//上一关
        var againButton = createButton(btnX * 2 + btnWidth, btnY, btnWidth, btnHeight, 0x000000, "重玩本关", 0xffffff);//重玩本关
        var nextButton = createButton(btnX * 3 + btnWidth * 2, btnY, btnWidth, btnHeight, 0x000000, "下一关", 0xffffff);//下一关
        this.addChild(prevButton);
        this.addChild(againButton);
        this.addChild(nextButton);
        prevButton.touchEnabled = true;
        againButton.touchEnabled = true;
        nextButton.touchEnabled = true;
        //按钮添加事件（上一关/重玩本关/下一个）
        prevButton.addEventListener(egret.TouchEvent.TOUCH_TAP, function () {
            This.touchEnabled=false;
            guanqiaNum--;
            if (guanqiaNum < 0) {
                guanqiaNum = 0;
            }
            renimg = "down_png"
            copylevels();
            mapAddpic();
        }, this);
        againButton.addEventListener(egret.TouchEvent.TOUCH_TAP, function () {
            This.touchEnabled=false;
            renimg = "down_png";
            copylevels();
            mapAddpic();
        }, this)
        nextButton.addEventListener(egret.TouchEvent.TOUCH_TAP, function () {
            guanqiaNum++;
            if (guanqiaNum > 99) {
                guanqiaNum = 99;
            }
            This.touchEnabled=false;
            renimg = "down_png";
            copylevels();
            mapAddpic();
        }, this)



        //深拷贝数组
        var newlevels = [];
        copylevels();
        function copylevels() {
            newlevels = [];
            for (var i = 0; i < levels.length; i++) {
                newlevels.push([]);
                for (var j = 0; j < levels[i].length; j++) {
                    newlevels[i].push(levels[i][j].concat())
                }
            }
        }


        //清空地图
        function clearMap() {
            for (var i = 0; i < picArr.length; i++) {
                This.removeChild(picArr[i]);
            }
        }



        //地图添加物品
        mapAddpic();
        function mapAddpic() {
            This.touchEnabled=true;
            clearMap();//清除所有地图上的物品
            picArr = [];//地图上对象数组清空
            guanqiaText = createButton(195, dibanY-80, 250, 50, 0x000000, "第"+(guanqiaNum+1)+"关", 0xffffff);//关数
            This.addChild(guanqiaText);
            for (var i = 0; i < 16; i++) {
                for (var j = 0; j < 16; j++) {
                    mapPicFn(guanqiaNum, i, j);//在地图上添加物品图片
                }
            }
        }
        //初始化地图图片
        function mapPicFn(n, x, y) {
            var img, width, height;
            switch (newlevels[n][y][x]) {
                case 0:
                    break;
                case 1:
                    img = "wall_png";
                    width = 35;
                    height = 46;
                    picFn(x, y, img, width, height);
                    break;
                case 2:
                    img = "ball_png";
                    width = 30;
                    height = 30;
                    picFn(x, y, img, width, height);
                    break;
                case 3:
                    img = "box_png";
                    width = 35;
                    height = 45;
                    picFn(x, y, img, width, height);
                    break;
                case 4:
                    img = renimg;
                    width = 50;
                    height = 62;
                    renX = x;
                    renY = y;
                    picFn(x, y, img, width, height);
                    break;
                case 5:
                    img = "box_png";
                    width = 35;
                    height = 45;
                    picFn(x, y, img, width, height);
                    break;
            }
        }
        //创建物品图片
        function picFn(x, y, img, width, height) {
            var dibanBitmap = new egret.Bitmap(RES.getRes(img));
            dibanBitmap.x = x * 35 + dibanX - (width - 35) / 2;
            dibanBitmap.y = y * 35 + dibanY - (height - 35);
            dibanBitmap.width = width;
            dibanBitmap.height = height;
            picArr.push(dibanBitmap);
            This.addChild(dibanBitmap);
        }
        //检测是否推箱子成功
        function xiayiguan() {
            for (var i = 0; i < 16; i++) {
                for (var j = 0; j < 16; j++) {
                    if (newlevels[guanqiaNum][j][i] == 3) {
                        return false;
                    }
                }
            }
            return true;
        }
        //滑动事件（begin事件+end事件）
        var beginX, beginY, endX, endY;
        This.addEventListener(egret.TouchEvent.TOUCH_BEGIN, function (e) {
            beginX = e.stageX;
            beginY = e.stageY;
        }, this)
        This.addEventListener(egret.TouchEvent.TOUCH_END, function (e) {
            endX = e.stageX;
            endY = e.stageY;
            var cX = endX - beginX;//滑动的X距离
            var cY = endY - beginY;//滑动的Y距离
            var absCX = Math.abs(cX);
            var absCY = Math.abs(cY);
            if (absCX > absCY && cX < 0) {//左移动
                renimg = "left_png";
                go(renX - 1, renY, renX - 2, renY);
            } else if (absCX > absCY && cX > 0) {//右移动
                renimg = "right_png";
                go(renX + 1, renY, renX + 2, renY);
            } else if (absCX < absCY && cY < 0) {//上移动
                renimg = "up_png";
                go(renX, renY - 1, renX, renY - 2);
            } else if (absCX < absCY && cY > 0) {//下移动
                renimg = "down_png";
                go(renX, renY + 1, renX, renY + 2);
            }
        }, this)
        function go(nextrenX, nextrenY, nextren2X, nextren2Y) {
            var next1Type = newlevels[guanqiaNum][nextrenY][nextrenX];//人物下一个格子类型
            var next2Type = newlevels[guanqiaNum][nextren2Y][nextren2X];//人物下两个格子类型
            if (next1Type == 0 || next1Type == 2) {
                newlevels[guanqiaNum][nextrenY][nextrenX] = 4;
                if (levels[guanqiaNum][renY][renX] == 2 || levels[guanqiaNum][renY][renX] == 5) {
                    newlevels[guanqiaNum][renY][renX] = 2;
                } else {
                    newlevels[guanqiaNum][renY][renX] = 0;
                }
                renX = nextrenX;
                renY = nextrenY;
                mapAddpic();
            } else if ((next1Type == 3 || next1Type == 5) && (next2Type == 0 || next2Type == 2)) {
                newlevels[guanqiaNum][nextrenY][nextrenX] = 4;
                if (levels[guanqiaNum][renY][renX] == 2 || levels[guanqiaNum][renY][renX] == 5) {
                    newlevels[guanqiaNum][renY][renX] = 2;
                } else {
                    newlevels[guanqiaNum][renY][renX] = 0;
                }
                if (levels[guanqiaNum][nextren2Y][nextren2X] == 2 || levels[guanqiaNum][nextren2Y][nextren2X] == 5) {
                    newlevels[guanqiaNum][nextren2Y][nextren2X] = 5;
                } else {
                    newlevels[guanqiaNum][nextren2Y][nextren2X] = 3;
                }
                renX = nextrenX;
                renY = nextrenY;
                mapAddpic();
                if (xiayiguan()) {
                    guanqiaNum++;
                    mapAddpic();
                }
            }
        }












    }

    /**
     * 根据name关键字创建一个Bitmap对象。name属性请参考resources/resource.json配置文件的内容。
     * Create a Bitmap object according to name keyword.As for the property of name please refer to the configuration file of resources/resource.json.
     */
    private createBitmapByName(name: string) {
        let result = new egret.Bitmap();
        let texture: egret.Texture = RES.getRes(name);
        result.texture = texture;
        return result;
    }

    /**
     * 描述文件加载成功，开始播放动画
     * Description file loading is successful, start to play the animation
     */
    private startAnimation(result: string[]) {
        let parser = new egret.HtmlTextParser();

        let textflowArr = result.map(text => parser.parse(text));
        let textfield = this.textfield;
        let count = -1;
        let change = () => {
            count++;
            if (count >= textflowArr.length) {
                count = 0;
            }
            let textFlow = textflowArr[count];

            // 切换描述内容
            // Switch to described content
            textfield.textFlow = textFlow;
            let tw = egret.Tween.get(textfield);
            tw.to({ "alpha": 1 }, 200);
            tw.wait(2000);
            tw.to({ "alpha": 0 }, 200);
            tw.call(change, this);
        };

        change();
    }
}


